package com.xiaoshi.translator;

import com.xiaoshi.enums.JsonReturnEnums;
import com.xiaoshi.exception.PlatformException;
import com.xiaoshi.utils.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
import org.springframework.security.oauth2.common.exceptions.InvalidRequestException;
import org.springframework.security.oauth2.common.exceptions.UnsupportedGrantTypeException;
import org.springframework.security.oauth2.provider.error.WebResponseExceptionTranslator;
import org.springframework.stereotype.Component;

/**
 * 异常翻译
 */
@Slf4j
@Component
public class ResWebResponseExceptionTranslator implements WebResponseExceptionTranslator {

    @Override
    public ResponseEntity translate(Exception e) {
        ResponseEntity.BodyBuilder status = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR);

        log.error("e={}", e);
        if (e instanceof UnsupportedGrantTypeException) {
            String grantType = StringUtils.substringAfterLast(e.getMessage(), ": ");
            return status.body(JsonResult.failFormat(JsonReturnEnums.AUTHENTICATION_TYPE_ISNOT, grantType));
        }

        if (e instanceof PlatformException) {
            return status.body(JsonResult.fail(e.getMessage()));
        }

        if (e instanceof InternalAuthenticationServiceException) {
            if (StringUtils.containsIgnoreCase(e.getMessage(), "You have an error in your SQL syntax")) {
                return status.body(JsonResult.fail(JsonReturnEnums.SQL_ERRER));
            }
            return status.body(JsonResult.fail(e.getMessage()));
        }

        if (e instanceof InvalidRequestException) {
            if (StringUtils.containsIgnoreCase(e.getMessage(), "Missing grant type")) {
                return status.body(JsonResult.fail(JsonReturnEnums.NOT_FIND_GRANT_TYPE));
            }
        }

        if (e instanceof InvalidGrantException) {
            if (StringUtils.containsIgnoreCase(e.getMessage(), "Invalid refresh token")) {
                status = ResponseEntity.status(HttpStatus.UNAUTHORIZED);
                return status.body(JsonResult.fail(JsonReturnEnums.REFRESH_TOKEN_INVALID));
            }
            if (StringUtils.containsIgnoreCase(e.getMessage(), "locked")) {
                return status.body(JsonResult.fail(JsonReturnEnums.USER_ISLOCK));
            }
            if (StringUtils.containsIgnoreCase(e.getMessage(), "Bad credentials")) {
                return status.body(JsonResult.fail(JsonReturnEnums.PASSWORD_ERRER));
            }

        }

        if (e instanceof InvalidClientException) {
            if (StringUtils.containsIgnoreCase(e.getMessage(), "Unauthorized grant type")) {
                String grantType = StringUtils.substringAfterLast(e.getMessage(), ": ");
                return status.body(JsonResult.failFormat(JsonReturnEnums.AUTHENTICATION_TYPE_ISNOT, grantType));
            }
        }

        if (e instanceof BadCredentialsException) {
            if (StringUtils.containsIgnoreCase(e.getMessage(), "Unauthorized grant type")) {
                return status.body(JsonResult.fail(JsonReturnEnums.PASSWORD_ERRER));
            }

            if (StringUtils.containsIgnoreCase(e.getMessage(), "Bad credentials")) {
                return status.body(JsonResult.fail(JsonReturnEnums.PASSWORD_ERRER));
            }
        }

        if (e instanceof IncorrectResultSizeDataAccessException) {
            return status.body(JsonResult.fail(JsonReturnEnums.OAUTH_TOKEN_CONCURRENCY));
        }

        return status.body(JsonResult.fail(JsonReturnEnums.AUTHENTICATION_FAIL));
    }
}
